﻿using ImperialServer.Common.Entities;
using ImperialServer.Data.DAO;
using ImperialServer.Data.Interfaces;
using ImperialUtilities.Exceptions;
using ImperialUtilities.Utilities;
using ImperialWebSite.Content.Resources;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;

namespace ImperialWebSite.Controllers
{
    public class SpecieController : BaseController
    {
        private IRegistryAccess _daoRegistryAccess;
        private EventViewer _logger;

        public SpecieController()
        {
            _logger = new EventViewer("ImperialWebSite.Controllers");
            _daoRegistryAccess = new RegistryAccess(ConfigurationManager.ConnectionStrings["ImperialConnection"].ConnectionString);
        }

        /// <summary>
        /// Metodo que crea un objeto de tipo SpecieEntity
        /// </summary>
        /// <param name="specieNameText">nombre de la especie</param>
        /// <returns>objeto lleno</returns>
        internal SpecieEntity CreateNewSpecie(string specieNameText)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "CreateNewSpecie"));

            SpecieEntity newSpecie = null;
            try
            {
                newSpecie = new SpecieEntity
                {
                    SpecieName = specieNameText
                };

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("CreateNewSpecie", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "CreateNewSpecie"));
            }
            return newSpecie;
        }

        /// <summary>
        /// Metodo que se encarga de realizar la llamada al servidor para insertar una nueva especie
        /// </summary>
        /// <param name="newSpecie">objeto con los datos a insertar</param>
        /// <returns>true si fue exitosa, false si no</returns>
        internal bool InsertNewSpecie(SpecieEntity newSpecie)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "InsertNewSpecie"));

            bool isSuccess = false;
            try
            {
                isSuccess = _daoRegistryAccess.InsertNewSpecie(newSpecie);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("InsertNewSpecie", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "InsertNewSpecie"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que indica si un specieName ya se encuentra registrado
        /// </summary>
        /// <param name="specieName">nombre de especie</param>
        /// <param name="currentSpecies">lista de species ya registradas</param>
        /// <returns>true si existe, false si no</returns>
        internal bool SpecieAlreadyRegistered(string specieName, object currentSpecies)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "SpecieAlreadyRegistered"));

            bool found = false;
            try
            {
                DataTable dtCurrentSpecies = (DataTable)currentSpecies;
                DataRow[] drCurrentSpecie = dtCurrentSpecies.Select("specieName = '" + specieName.ToLower() + "'");
                found = drCurrentSpecie != null && drCurrentSpecie.Length > 0;

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("SpecieAlreadyRegistered", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "SpecieAlreadyRegistered"));
            }
            return found;
        }

        /// <summary>
        /// Metodo que se encarga de hacer la llamada al servidor para actualizar la informacion de una especie
        /// </summary>
        /// <param name="specieName">objeto con los datos a actualizar</param>
        /// <returns>true si es exitosa, false si no</returns>
        internal bool UpdateSpecie(SpecieEntity specie)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "UpdateSpecie"));

            bool isSuccess = false;
            try
            {
                isSuccess = _daoRegistryAccess.UpdateSpecie(specie);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("UpdateSpecie", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "UpdateSpecie"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que se encarga de consultar un registro para saber si es igual a un parametro
        /// </summary>
        /// <param name="specieName">nombre de especie</param>
        /// <param name="currentSpecies">coleccion de registros</param>
        /// <param name="currentSpecie">registro a consultar</param>
        /// <returns>true si es el mismo registro, false si no</returns>
        internal bool IsTheSameSpecie(string specieName, object currentSpecies, object currentSpecie)
        {
            HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "IsTheSameSpecie"));

            bool isSameSpecie = false;
            try
            {
                DataTable dtCurrentSpecies = (DataTable)currentSpecies;
                DataRow[] drCurrentSpecie = dtCurrentSpecies.Select("idSpecie = " + currentSpecie.ToString());
                if (drCurrentSpecie != null && drCurrentSpecie.Length > 0)
                    isSameSpecie = drCurrentSpecie[0]["specieName"].ToString() == specieName;
                else
                {
                    _logger.WriteEventViewerLog("IsTheSameSpecie", Messages.failureTransactionMessage, true);
                    throw new ImperialException(Messages.failureTransactionMessage);
                }

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("IsTheSameSpecie", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "IsTheSameSpecie"));
            }
            return isSameSpecie;
        }
    }
}